package cn.tedu.v3;

import java.io.*;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;

/**
 * 多人聊天室 Version 3
 * Server服务器：找到CS多线程类
 *   1.读入放入线程中
 *   2.写出直接写在run方法
 */
public class Server {
    private ServerSocket serverSocket;
    public Server(){
        try {
            serverSocket=new ServerSocket(7777);
        } catch (BindException e){
            System.out.println("请检查端口号，被占用~");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void start() {
        Socket socket=null;
        String ip=null;
        try {
            while(true) {
                System.out.println("等待客户端连接");
                socket = serverSocket.accept();



                new Thread(new CS(socket)).start();
            }
        } catch (IOException e) {
            System.out.println(ip+"客户端链接断开链接~");
        } finally {
              if(serverSocket!=null&&!serverSocket.isClosed()){
                  try {
                      serverSocket.close();
                  } catch (IOException e) {
                      System.out.println("服务器关闭失败~~~");
                  }
                  System.out.println("服务器关闭成功~~Over");
              }
        }
    }
    public static void main(String[] args){
        Server server=new Server();
        server.start();
    }
    //CS 多线程类：控制客户端发来的通讯消息
    private class CS implements Runnable {

        private Socket socket;

        private String ip;


        public CS(Socket s){
            this.socket=s;
            ip=socket.getInetAddress().getHostAddress();
        }



        public void run() {
            PrintWriter pw=null;
            //BufferedReader br = null;
            try {
                //1.输出流--直接写出在run方法中
                //1.2读入操作
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
                //2.输入读入功能：存入线程中
                //1.1写出操作
                pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF8")),true);

                //1.3 创建线程---Lanbda---读入功能--存入线程中
                new Thread(()->{
                //1.4 线程中--创建变量--接收客户端发来文本
                    try {
                        String message;
                        while ((message=br.readLine())!=null) { //读入客户端
                            System.out.println(ip+"客户端：" +message);
                            //1.6 增加一句话--每次客户端发给服务器内容
                            System.out.println("服务器请输入：");
                        }
                    } catch (IOException e) {
                        System.out.println("客户端发来的消息断开了");
                    }
                }).start();

         //1.5 增加写出操作【修改目的：读入写出通顺】
         //1.5.1 控制台卡住--输入内容
                Scanner input=new Scanner(System.in);
         //1.5.2 一直写出
         while(true){
             System.out.println("服务器请输入：");
             String sme=input.nextLine();
             pw.println("服务器说："+sme);
         }
            } catch (UnsupportedEncodingException e) {
                System.out.println("请检查客户端/服务器端编码集：不一致~");
            } catch (SocketException e) {
                System.out.println("客户端链接被重置了~");
            } catch (IOException e) {
                System.out.println("客户端链接失效了~");
            } finally {
//                if (br != null)
//                    try {
//                        br.close();
//                    } catch (IOException e) {
//                        System.out.println("读入流断开链接~");
//                    }
                if(socket!=null&&!socket.isClosed()){
                    System.out.println(ip+"客户端退出服务器连接~");
                    try {
                        socket.close();
                    } catch (IOException e) {
                        System.out.println(ip+"客户端退出连接异常~");
                    }
                }
            }
        }
    }
}
